import 'dart:async';

import 'package:audioplayers/audioplayers.dart';

enum PlayResult {
  cancel,
  completed,
  error,
}

class AudioPlayManager {
  StreamSubscription<void>? completeListener;
  AudioPlayer player = AudioPlayer();
  Completer<PlayResult>? completer;

  AudioPlayManager() {
    player.audioCache = AudioPlayManager.audioCache;
  }

  void release({PlayResult? state = PlayResult.completed, Object? err}) {
    player.release();
    if (state == PlayResult.error) {
      completer?.completeError(err ?? '');
    } else {
      completer?.complete(state);
    }
    completer = null;
    completeListener?.cancel();
    completeListener = null;
  }

  void dispose() {
    release(state: PlayResult.cancel);
    player.dispose();
  }

  Future<PlayResult> mediaPlay(String assets) {
    release(state: PlayResult.cancel);
    completer = Completer<PlayResult>();
    completeListener = player.onPlayerComplete.listen((state) {
      release();
    });
    player
        .play(AssetSource(assets.replaceFirst(RegExp('^/'), '')),
            mode: PlayerMode.mediaPlayer)
        .catchError((err) {
      release(state: PlayResult.error, err: err);
    });
    return completer!.future;
  }

  static AudioCache audioCache = AudioCache(prefix: '');

  static void lowLatencyPlay(String assets) {
    final player = AudioPlayer();
    player.audioCache = audioCache;
    player.play(AssetSource(assets.replaceFirst(RegExp('^/'), '')),
        mode: PlayerMode.lowLatency);
  }
}
